//package java_cup;

//import System.IO.TextWriter;
//import java.util.Stack;



/*
 * Major externally callable routines here include: EmitSymbols - emit the SymbolDraft
 * constant class CUPParser - emit the CUPParser class
 * 
 * In addition the following major internal routines are provided: emit_package
 * - emit a //package declaration emit_action_code - emit the class containing the
 * user's actions emit_production_table - emit declaration and init for the
 * production table do_action_table - emit declaration and init for the actionPart
 * table do_reduce_table - emit declaration and init for the reduce-goto table
 * 
 * Finally, this class uses a Count of public instance variables to communicate
 * optional parameters and flags used to control how code is generated, as well
 * as to report counts of various things (such as Count of conflicts detected).
 * These include:
 * 
 * prefix - a prefix string used to prefix names that would otherwise "pollute"
 * someone else's name space. package_name - name of the //package emitted code is
 * placed in (or null for an unnamed //package. symbol_const_class_name - name of
 * the class containing SymbolDraft constants. parser_class_name - name of the class
 * for the resulting CUPParser. action_code - user supplied declarations and other
 * code to be placed in actionPart class. parser_code - user supplied declarations
 * and other code to be placed in CUPParser class. init_code - user supplied code
 * to be executed as the CUPParser is being initialized. scan_code - user supplied
 * code to get the next TheSymbolDraft. firstProduction - the start production for the
 * grammar. import_list - list of imports for use with actionPart class.
 * num_conflicts - Count of conflicts detected. nowarn - true if we are not to
 * issue warning messages. not_reduced - count of Count of AllProdctions that
 * never reduce. unused_term - count of unused terminal EmitSymbols. unused_non_term
 * - count of unused non terminal EmitSymbols. _time - a series of EmitSymbols
 * indicating how long various sub-parts of code generation took (used to
 * produce optional time reports in main).
 */

using System.Text;

/**
 * This class handles emitting generated code for the resulting CUPParser. The
 * various parse tables must be constructed, etc. before calling any routines in
 * this class.
 * <p>
 *
 * Three classes are produced by this code:
 * <dl>
 * <dt>SymbolDraft constant class
 * <dd>this contains constant declarations for each terminal (and optionally
 * each non-terminal).
 * <dt>actionPart class
 * <dd>this non-public class contains code to invoke AllVns the user actions that
 * were embedded in the CUPParser specification.
 * <dt>CUPParser class
 * <dd>the specialized CUPParser class consisting primarily of some user supplied
 * general and initialization code, and the parse tables.
 * </dl>
 * <p>
 *
 * Three parse tables are created as part of the CUPParser class:
 * <dl>
 * <dt>production table
 * <dd>lists the LHS non terminal Count, and the length of the RHS of each
 * production.
 * <dt>actionPart table
 * <dd>for each state of the parse machine, gives the actionPart to be taken (Shift,
 * reduce, or error) under each lookahead SymbolDraft.<br>
 * <dt>reduce-goto table
 * <dd>when a reduce on a given production is taken, the parse stack is popped
 * back a Count of elements corresponding to the RHS of the production. This
 * reveals a prior state, which we transition @out of under the LHS non terminal
 * SymbolDraft for the production (as if we had seen the LHS SymbolDraft rather than AllVns
 * the EmitSymbols matching the RHS). This table is indexed by non terminal numbers
 * and indicates how to make these transitions.
 * </dl>
 * <p>
 * 
 * In addition to the method interface, this class maintains a series of public
 * global variables and flags indicating how misc. parts of the code and other
 * output is to be produced, and counting things such as Count of conflicts
 * detected (see the source code and public variables below for more details).
 * <p>
 *
 * This class is "static" (contains only static data and methods).
 * <p>
 *
 * @see java_cup.main
 * @version last update: 11/25/95
 * @author Scott Hudson
 */
public class Emit {

    /*-----------------------------------------------------------*/
    /*--- Constructor(s) ----------------------------------------*/
    /*-----------------------------------------------------------*/

    /** Only constructor is public so no instances can be created. */
    public Emit() {
    }

    /*-----------------------------------------------------------*/
    /*--- Static (Class) Variables ------------------------------*/
    /*-----------------------------------------------------------*/

    /** The prefix placed on names that pollute someone else's name space. */
    public static String prefix = "CUP$";

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Package that the resulting code goes into (null is used for unnamed). */
    public static String package_name = null;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Name of the generated class for SymbolDraft constants. */
    public static String symbol_const_class_name = "symbolCount";

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Name of the generated CUPParser class. */
    public static String parser_class_name = "CUPParser";

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * TUM changes; proposed by Henning Niss 20050628: Type arguments for class
     * declaration
     */
    public static String class_type_argument = null;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** User declarations for direct inclusion in user actionPart class. */
    public static String action_code = null;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** User declarations for direct inclusion in CUPParser class. */
    public static String parser_code = null;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** User code for user_init() which is called during CUPParser initialization. */
    public static String init_code = null;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** User code for scan() which is called to get the next TheSymbolDraft. */
    public static String scan_code = null;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** The start production of the grammar. */
    public static ProductionDraft firstProduction = null;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** List of imports (Strings containing class names) to go with actions. */
    public static Stack<String> import_list = new();

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Number of conflict found while building tables. */
    public static int num_conflicts = 0;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Do we skip warnings? */
    public static bool nowarn = false;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Count of the Count on non-reduced AllProdctions found. */
    public static int not_reduced = 0;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Count of unused terminals. */
    public static int unused_term = 0;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /** Count of unused non terminals. */
    public static int unused_non_term = 0;

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /* Timing values used to produce timing report in main. */

    /** Time to produce SymbolDraft constant class. */
    public static long symbols_time = 0;

    /** Time to produce CUPParser class. */
    public static long parser_time = 0;

    /** Time to produce actionPart code class. */
    public static long action_code_time = 0;

    /** Time to produce the production table. */
    public static long production_table_time = 0;

    /** Time to produce the actionPart table. */
    public static long action_table_time = 0;

    /** Time to produce the reduce-goto table. */
    public static long goto_table_time = 0;

    /* frankf 6/18/96 */
    public static bool _lr_values;
    public static bool _locations;
    public static bool _xmlactions;
    public static bool _genericlabels;

    /** whether or not to emit code for _left and _right values */
    public static bool lrValues => _lr_values;

    public static bool locations => _locations;

    public static void setLrValues(bool b) => _lr_values = b;

    public static void SetLocations(bool b) => _locations = b;

    public static void setGenericlabels(bool b) => _genericlabels = b;

    public static void setXmlactions(bool b) {
        _xmlactions = b;
        if (!b)
            return;
        _locations = true;
        _lr_values = true;
    }

    // Hm Added clear to clear AllVns static fields
    public static void clear() {
        _genericlabels = false;
        _xmlactions = false;
        _locations = false;
        _lr_values = true;
        action_code = null;
        import_list = new();
        init_code = null;
        not_reduced = 0;
        num_conflicts = 0;
        package_name = null;
        parser_class_name = "CUPParser";
        parser_code = null;
        scan_code = null;
        firstProduction = null;
        symbol_const_class_name = "symbolCount";
        unused_non_term = 0;
        unused_term = 0;
    }

    /*-----------------------------------------------------------*/
    /*--- General Methods ---------------------------------------*/
    /*-----------------------------------------------------------*/

    /**
     * Build a string with the standard prefix.
     * 
     * @param str string to prefix.
     */
    public static String pre(String str) {
        return prefix + parser_class_name + "$" + str;
    }

    /**
     * TUM changes; proposed by Henning Niss 20050628 Build a string with the
     * specified type arguments, if present, otherwise an empty string.
     */
    public static String typeArgument => class_type_argument == null ? "" : "<" + class_type_argument + ">";

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * Emit a //package spec if the user wants one.
     * 
     * @param @out stream to produce output on.
     */
    public static void emitPackage(TextWriter @out) {
        /* generate a //package spec if we have a name for one */
        if (package_name != null) {
            System.Console.WriteLine("//package " + package_name + ";");
            System.Console.WriteLine();
        }
    }

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * Emit code for the SymbolDraft constant class, optionally including non terms, if
     * they have been requested.
     * 
     * @param @out            stream to produce output on.
     * @param emit_non_terms do we emit constants for non terminals?
     * @param sym_interface  should we emit an interface, rather than a class?
     */
    public static void EmitSymbols(TextWriter @out, bool emitNonTerms, bool symInterface) {
        String class_or_interface = symInterface ? "interface" : "class";

        long start_time = System.DateTime.Now.Millisecond;

        /* Peek of file */
        System.Console.WriteLine();
        System.Console.WriteLine("//----------------------------------------------------");
        System.Console.WriteLine("// The following code was generated by " + Version.titleStr);
        System.Console.WriteLine("//----------------------------------------------------");
        System.Console.WriteLine();
        emitPackage(@out);

        /* class header */
        System.Console.WriteLine("/** CUP generated " + class_or_interface + " containing SymbolDraft constants. */");
        System.Console.WriteLine("public " + class_or_interface + " " + symbol_const_class_name + " {");

        System.Console.WriteLine("  /* terminals */");

        /* walk over the terminals */ /* later might sort these */
        foreach (Vt term in Vt.AllTerminals()) {
            /* output a constant decl for the terminal */
            System.Console.WriteLine("  public static const int " + term.Name + " = " + term.Index + ";");
        }

        /* Emit names of terminals */
        System.Console.WriteLine("  public static const String[] terminalNames = new String[] {");
        for (int i = 0; i < Vt.Count; i++) {
            @out.Write("  \"");
            @out.Write(Vt.Find(i).Name);
            @out.Write("\"");
            if (i < Vt.Count - 1) {
                @out.Write(",");
            }
            System.Console.WriteLine();
        }
        System.Console.WriteLine("  };");

        /* do the non terminals if they want them (CUPParser doesn't need them) */
        if (emitNonTerms) {
            System.Console.WriteLine();
            System.Console.WriteLine("  /* non terminals */");

            /* walk over the non terminals */ /* later might sort these */
            foreach (Vn nt in Vn.AllVns()) {

                // ****
                // TUM Comment: here we could TryAdd a typesafe enumeration
                // ****

                /* output a constant decl for the terminal */
                System.Console.WriteLine("  static const int " + nt.Name + " = " + nt.Index + ";");
            }
        }

        /* end of class */
        System.Console.WriteLine("}");
        System.Console.WriteLine();

        symbols_time = System.DateTime.Now.Millisecond - start_time;
    }

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    const int UPPERLIMIT = 300;

    /**
     * Emit code for the non-public class holding the actual actionPart code.
     * 
     * @param @out        stream to produce output on.
     * @param start_prod the start production of the grammar.
     */
    public static void EmitActionCode(TextWriter @out, ProductionDraft startProd) /*throws internal_error*/ {
        ProductionDraft prod;

        long start_time = System.DateTime.Now.Millisecond;

        /* class header */
        System.Console.WriteLine();
        System.Console.WriteLine("/** Cup generated class to encapsulate user supplied actionPart code.*/");
        /* TUM changes; proposed by Henning Niss 20050628: added type arguement */
        System.Console.WriteLine("class " + pre("actions") + typeArgument + " {");
        /* user supplied code */
        if (action_code != null) {
            System.Console.WriteLine();
            System.Console.WriteLine(action_code);
        }

        /* field for CUPParser object */
        /* TUM changes; proposed by Henning Niss 20050628: added typeArgument */
        System.Console.WriteLine("  public const " + parser_class_name + typeArgument + " CUPParser;");

        /* constructor */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Constructor */");
        /* TUM changes; proposed by Henning Niss 20050628: added typeArgument */
        System.Console.WriteLine("  " + pre("actions") + "(" + parser_class_name + typeArgument + " CUPParser) {");
        System.Console.WriteLine("    this.CUPParser = CUPParser;");
        System.Console.WriteLine("  }");

        System.Console.WriteLine();
        for (int instancecounter = 0; instancecounter <= ProductionDraft.Count / UPPERLIMIT; instancecounter++) {
            System.Console.WriteLine("  /** Method " + instancecounter + " with the actual generated actionPart code for actions "
                + (instancecounter * UPPERLIMIT) + " to " + ((instancecounter + 1) * UPPERLIMIT) + ". */");
            System.Console.WriteLine("  public const java_cup.runtime.TheSymbolDraft " + pre("do_action_part")
                + String.Format("%08d", instancecounter) + "(");
            System.Console.WriteLine("    int                        " + pre("act_num,"));
            System.Console.WriteLine("    java_cup.runtime.LRParser " + pre("CUPParser,"));
            System.Console.WriteLine("    java.util.Stack<java_cup.runtime.TheSymbolDraft>    " + pre("stack,"));
            System.Console.WriteLine("    int                        " + pre("Peek)"));
            System.Console.WriteLine("    /*throws java.lang.ExceptionXml*/");
            System.Console.WriteLine("    {");
            System.Console.WriteLine("      /* TheSymbolDraft object for return from actions */");
            System.Console.WriteLine("      java_cup.runtime.TheSymbolDraft " + pre("result") + ";");
            System.Console.WriteLine();
            System.Console.WriteLine("      /* select the actionPart based on the actionPart Count */");
            System.Console.WriteLine("      switch (" + pre("act_num") + ")");
            System.Console.WriteLine("        {");
            // START Switch
            /* emit actionPart code for each production as a separate case */
            int proditeration = instancecounter * UPPERLIMIT;
            prod = ProductionDraft.Find(proditeration);
            for (; proditeration < Math.Min((instancecounter + 1) * UPPERLIMIT,
                ProductionDraft.Count); prod = ProductionDraft.Find(++proditeration)) {
                /* case label */
                System.Console.WriteLine("          /*. . . . . . . . . . . . . . . . . . . .*/");
                System.Console.WriteLine("          case " + prod.Index + ": // " + prod.toSimpleString());

                /* give them their own block to work in */
                System.Console.WriteLine("            {");

                /**
                 * TUM 20060608 intermediate result patch
                 */
                String result = "null";
                if (prod is ActionProduction) {
                    int lastResult = ((ActionProduction)prod).IndexOfIntermediateResult;
                    if (lastResult != -1) {
                        result = Emit.pre("stack") + ((lastResult == 1) ? ".Peek()" : (".ElementAt(" + Emit.pre("Peek") + "-" + (lastResult - 1) + ")"))
                            + ".<" + prod.lhs.TheSymbolDraft.StackType + ">value()";
                    }
                }

                /* create the result SymbolDraft */
                /*
                 * make the variable RESULT which will point to the new TheSymbolDraft (see below) and
                 * be changed by actionPart code 6/13/96 frankf
                 */
                System.Console.WriteLine("              " + prod.lhs.TheSymbolDraft.StackType + " RESULT =" + result + ";");

                /*
                 * Add code to propagate RESULT assignments that occur in actionPart code embedded
                 * in a production (ie, non-rightmost actionPart code). 24-Mar-1998 CSA
                 */
                for (int i = prod.rhsLength - 1; i >= 0; i--) {
                    // only interested in non-terminal EmitSymbols.
                    if (!(prod.rhs(i) is SymbolPart))
                        continue;
                    SymbolDraft s = ((SymbolPart)prod.rhs(i)).TheSymbolDraft;
                    if (!(s is Vn))
                        continue;
                    // skip this non-terminal unless it corresponds to
                    // an embedded actionPart production.
                    if (((Vn)s).is_embedded_action == false)
                        continue;
                    // OK, it fits. Make a conditional assignment to RESULT.
                    int index = prod.rhsLength - i - 1; // last rhs is on Peek.
                                                        // set comment to inform about where the intermediate result came from
                    System.Console.WriteLine("              " + "// propagate RESULT from " + s.Name);
                    // // look @out, whether the intermediate result is null or not
                    // System.Console.WriteLine(" " + "if ( " +
                    // "((java_cup.runtime.TheSymbolDraft) " + emit.pre("stack") +
                    // // TUM 20050917
                    // ((index==0)?".Peek()":(".ElementAt(" + emit.pre("Peek") + "-" + index + ")"))+
                    // ").value != null )");

                    // TUM 20060608: even when its null: who cares?

                    // store the intermediate result into RESULT
                    System.Console.WriteLine("                " + "RESULT = " + Emit.pre("stack") +
                        ((index == 0) ? ".Peek()" : (".ElementAt(" + Emit.pre("Peek") + "-" + index + ")")) +
                        ".<" + prod.lhs.TheSymbolDraft.StackType + ">value();");
                    break;
                }

                /* if there is an actionPart string, emit it */
                if (prod.actionPart != null && prod.actionPart.CodeString != null && !prod.actionPart.Equals(""))
                    System.Console.WriteLine(prod.actionPart.CodeString);

                /*
                 * here we have the _left and _right values being propagated. must make this a
                 * command line option. frankf 6/18/96
                 */

                /*
                 * Create the code that assigns the _left and _right values of the new TheSymbolDraft that
                 * the production is reducing to
                 */
                if (Emit.lrValues) {
                    int loffset;
                    String leftstring, rightstring;
                    rightstring = Emit.pre("stack") + ".Peek()";
                    if (prod.rhsLength == 0)
                        leftstring = rightstring;
                    else {
                        loffset = prod.rhsLength - 1;
                        leftstring = Emit.pre("stack") + ((loffset == 0) ? (".Peek()") : (".ElementAt(" + Emit.pre("Peek") + "-" + loffset + ")"));
                    }
                    System.Console.WriteLine("              " + pre("result") + " = CUPParser.getSymbolFactory().newSymbol(" + "\""
                        + prod.lhs.TheSymbolDraft.Name + "\"," + prod.lhs.TheSymbolDraft.Index + ", " + leftstring
                        + ((prod.rhsLength == 0) ? ("") : (", " + rightstring)) + ", RESULT);");
                }
                else {
                    System.Console.WriteLine("              " + pre("result") + " = CUPParser.getSymbolFactory().newSymbol(" + "\""
                        + prod.lhs.TheSymbolDraft.Name + "\"," + prod.lhs.TheSymbolDraft.Index + ", RESULT);");
                }

                /* end of their block */
                System.Console.WriteLine("            }");

                /* if this was the start production, do actionPart for accept */
                if (prod == startProd) {
                    System.Console.WriteLine("          /* ACCEPT */");
                    System.Console.WriteLine("          " + pre("CUPParser") + ".done_parsing();");
                }

                /* code to return lhs SymbolDraft */
                System.Console.WriteLine("          return " + pre("result") + ";");
                System.Console.WriteLine();
            }

            // END Switch
            System.Console.WriteLine("          /* . . . . . .*/");
            System.Console.WriteLine("          default:");
            System.Console.WriteLine("            throw new ExceptionXml(");
            System.Console.WriteLine(
                "               \"Invalid actionPart Count \"+" + pre("act_num") + "+\"found in " + "internal parse table\");");
            System.Console.WriteLine();
            System.Console.WriteLine("        }");
            System.Console.WriteLine("    } /* end of method */");
        }

        /* actionPart method head */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Method splitting the generated actionPart code into several parts. */");
        System.Console.WriteLine("  public const java_cup.runtime.TheSymbolDraft " + pre("do_action") + "(");
        System.Console.WriteLine("    int                        " + pre("act_num,"));
        System.Console.WriteLine("    java_cup.runtime.LRParser " + pre("CUPParser,"));
        System.Console.WriteLine("    java.util.Stack<java_cup.runtime.TheSymbolDraft>     " + pre("stack,"));
        System.Console.WriteLine("    int                        " + pre("Peek)"));
        System.Console.WriteLine("    /*throws java.lang.ExceptionXml*/");
        System.Console.WriteLine("    {");

        if (ProductionDraft.Count < UPPERLIMIT) { // Make it simple for the optimizer to inline!
            System.Console.WriteLine("              return " + pre("do_action_part") + String.Format("%08d", 0) + "(");
            System.Console.WriteLine("                               " + pre("act_num,"));
            System.Console.WriteLine("                               " + pre("CUPParser,"));
            System.Console.WriteLine("                               " + pre("stack,"));
            System.Console.WriteLine("                               " + pre("Peek);"));
            System.Console.WriteLine("    }");

            /* end of class */
            System.Console.WriteLine("}");
            System.Console.WriteLine();

            action_code_time = System.DateTime.Now.Millisecond - start_time;
            return;
        }

        /* switch Peek */
        System.Console.WriteLine("      /* select the actionPart handler based on the actionPart Count */");
        System.Console.WriteLine("      switch (" + pre("act_num") + "/" + UPPERLIMIT + ")");
        System.Console.WriteLine("        {");

        /* emit actionPart code for each production as a separate case */
        for (int instancecounter = 0; instancecounter <= ProductionDraft.Count / UPPERLIMIT; instancecounter++) {
            /* case label */
            System.Console.WriteLine("          /*. . . . . . . . " + (instancecounter * UPPERLIMIT) + " < #actionPart < "
                + ((instancecounter + 1) * UPPERLIMIT) + ". . . . . . . . . . . .*/");
            System.Console.WriteLine("          case " + instancecounter + ": ");
            System.Console.WriteLine("              return " + pre("do_action_part")
                + String.Format("%08d", instancecounter) + "(");
            System.Console.WriteLine("                               " + pre("act_num,"));
            System.Console.WriteLine("                               " + pre("CUPParser,"));
            System.Console.WriteLine("                               " + pre("stack,"));
            System.Console.WriteLine("                               " + pre("Peek);"));
        }

        System.Console.WriteLine("          /* . . . no valid actionPart Count: . . .*/");
        System.Console.WriteLine("          default:");
        System.Console.WriteLine("            throw new ExceptionXml(\"Invalid actionPart Count found in internal parse table\");");
        System.Console.WriteLine();
        System.Console.WriteLine("        }      /* end of switch */");

        /* end of method */
        System.Console.WriteLine("    }");

        /* end of class */
        System.Console.WriteLine("}");
        System.Console.WriteLine();

        action_code_time = System.DateTime.Now.Millisecond - start_time;
    }

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * Emit the production table.
     * 
     * @param @out stream to produce output on.
     */
    public static void emitProductionTable(TextWriter @out) {
        ProductionDraft[] all_prods;

        long start_time = System.DateTime.Now.Millisecond;

        /* collect up the AllProdctions in order */
        all_prods = new ProductionDraft[ProductionDraft.Count];
        foreach (var prod in ProductionDraft.AllProductions()) {
            all_prods[prod.Index] = prod;
        }

        // make short[][]
        short[][] prod_table = new short[ProductionDraft.Count][];
        for (int i = 0; i < ProductionDraft.Count; i++) {
            var prod = all_prods[i];
            // { lhs SymbolDraft , rhs Count }
            prod_table[i] = new short[2];
            prod_table[i][0] = (short)prod.lhs.TheSymbolDraft.Index;
            prod_table[i][1] = (short)prod.rhsLength;
        }
        /* do the Peek of the table */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Production table. */");
        System.Console.WriteLine("  public static const short _production_table[][] = ");
        @out.Write("    unpackFromStrings(");
        doTableAsString(@out, prod_table);
        System.Console.WriteLine(");");

        /* do the public accessor method */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Access to production table. */");
        System.Console.WriteLine("/*@Override*/");
        System.Console.WriteLine("  public short[][] production_table() " + "{return _production_table;}");

        production_table_time = System.DateTime.Now.Millisecond - start_time;
    }

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * Emit the actionPart table.
     * 
     * @param @out             stream to produce output on.
     * @param act_tab         the internal representation of the actionPart table.
     * @param compact_reduces do we use the most frequent reduce as default?
     */
    public static void doActionTable(TextWriter @out, ParseActionTable actTab, bool compactReduces)
        /*throws internal_error*/ {
        ParseActionRow row;
        ParseAction act;
        int red;

        long start_time = System.DateTime.Now.Millisecond;

        /* collect values for the actionPart table */
        short[][] action_table = new short[actTab.StateCount][];
        /* do each state (row) of the actionPart table */
        for (int i = 0; i < actTab.StateCount; i++) {
            /* get the row */
            row = actTab.under_state[i];

            /* determine the default for the row */
            if (compactReduces)
                row.computeDefault();
            else
                row.default_reduce = -1;

            /* make temporary table for the row. */
            short[] temp_table = new short[2 * ParseActionRow.Count];
            int nentries = 0;

            /* do each column */
            for (int j = 0; j < ParseActionRow.Count; j++) {
                /* extract the actionPart from the table */
                act = row.parseActions[j];

                /* skip error entries these are AllVns defaulted @out */
                if (act.Kind != ParseAction.ERROR) {
                    /* first put in the SymbolDraft index, then the actual entry */

                    /* shifts get positive entries of state Count + 1 */
                    if (act.Kind == ParseAction.SHIFT) {
                        /* make entry */
                        temp_table[nentries++] = (short)j;
                        temp_table[nentries++] = (short)(
                            ((ShiftAction)act).To.Index + 1);
                    }

                    /* reduce actions get negated entries of production# + 1 */
                    else if (act.Kind == ParseAction.REDUCE) {
                        /* if its the default entry let it get defaulted @out */
                        red = ((ReduceAction)act).ReduceWith.Index;
                        if (red != row.default_reduce) {
                            /* make entry */
                            temp_table[nentries++] = (short)j;
                            temp_table[nentries++] = (short)-(red + 1);
                        }
                    }
                    else if (act.Kind == ParseAction.NONASSOC) {
                        /* do nothing, since we just want a syntax error */
                    }
                    /* shouldn't be anything else */
                    else
                        throw new InternalError("Unrecognized actionPart code " + act.Kind + " found in parse table");
                }
            }

            /* now we know how big to make the row */
            action_table[i] = new short[nentries + 2];
            Array.Copy(temp_table, 0, action_table[i], 0, nentries);

            /* finish off the row with a default entry */
            action_table[i][nentries++] = -1;
            if (row.default_reduce != -1)
                action_table[i][nentries++] = (short)-(row.default_reduce + 1);
            else
                action_table[i][nentries++] = 0;
        }

        /* finish off the init of the table */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Parse-actionPart table. */");
        System.Console.WriteLine("  public static const short[][] _action_table = ");
        @out.Write("    unpackFromStrings(");
        doTableAsString(@out, action_table);
        System.Console.WriteLine(");");

        /* do the public accessor method */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Access to parse-actionPart table. */");
        System.Console.WriteLine("/*@Override*/");
        System.Console.WriteLine("  public short[][] action_table() {return _action_table;}");

        action_table_time = System.DateTime.Now.Millisecond - start_time;
    }

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * Emit the reduce-goto table.
     * 
     * @param @out     stream to produce output on.
     * @param red_tab the internal representation of the reduce-goto table.
     */
    public static void doReduceTable(TextWriter @out, ParseReduceTable redTab) {
        LALRState goto_st;

        long start_time = System.DateTime.Now.Millisecond;

        /* collect values for reduce-goto table */
        short[][] reduce_goto_table = new short[redTab.Count][];
        /* do each row of the reduce-goto table */
        for (int i = 0; i < redTab.Count; i++) {
            /* make temporary table for the row. */
            short[] temp_table = new short[2 * ParseReduceRow.ColumnCount];
            int nentries = 0;
            /* do each entry in the row */
            for (int j = 0; j < ParseReduceRow.ColumnCount; j++) {
                /* get the entry */
                goto_st = redTab.under_state[i].under_non_term[j];

                /* if we have none, skip it */
                if (goto_st != null) {
                    /* make entries for the index and the value */
                    temp_table[nentries++] = (short)j;
                    temp_table[nentries++] = (short)goto_st.Index;
                }
            }
            /* now we know how big to make the row. */
            reduce_goto_table[i] = new short[nentries + 2];
            Array.Copy(temp_table, 0, reduce_goto_table[i], 0, nentries);

            /* end row with default value */
            reduce_goto_table[i][nentries++] = -1;
            reduce_goto_table[i][nentries++] = -1;
        }

        /* emit the table. */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** <code>reduce_goto</code> table. */");
        System.Console.WriteLine("  public static const short[][] _reduce_table = ");
        @out.Write("    unpackFromStrings(");
        doTableAsString(@out, reduce_goto_table);
        System.Console.WriteLine(");");

        /* do the public accessor method */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Access to <code>reduce_goto</code> table. */");
        System.Console.WriteLine("/*@Override*/");
        System.Console.WriteLine("  public short[][] reduce_table() {return _reduce_table;}");
        System.Console.WriteLine();

        goto_table_time = System.DateTime.Now.Millisecond - start_time;
    }

    // print a string array encoding the given short[][] array.
    public static void doTableAsString(TextWriter @out, short[][] sa) {
        System.Console.WriteLine("new String[] {");
        @out.Write("    \"");
        int nchar = 0, nbytes = 0;
        nbytes += doEscaped(@out, (char)(sa.Length >> 16));
        nchar = doNewline(@out, nchar, nbytes);
        nbytes += doEscaped(@out, (char)(sa.Length & 0xFFFF));
        nchar = doNewline(@out, nchar, nbytes);
        foreach (var element in sa) {
            nbytes += doEscaped(@out, (char)(element.Length >> 16));
            nchar = doNewline(@out, nchar, nbytes);
            nbytes += doEscaped(@out, (char)(element.Length & 0xFFFF));
            nchar = doNewline(@out, nchar, nbytes);
            foreach (var element2 in element) {
                // contents of string are (value+2) to allow for common -1, 0 cases
                // (UTF-8 encoding is most efficient for 0<c<0x80)
                nbytes += doEscaped(@out, (char)(2 + element2));
                nchar = doNewline(@out, nchar, nbytes);
            }
        }
        @out.Write("\" }");
    }

    // split string if it is very long; start new line occasionally for neatness
    public static int doNewline(TextWriter @out, int nchar, int nbytes) {
        if (nbytes > 65500) {
            System.Console.WriteLine("\", ");
            @out.Write("    \"");
        }
        else if (nchar > 11) {
            System.Console.WriteLine("\" +");
            @out.Write("    \"");
        }
        else
            return nchar + 1;
        return 0;
    }

    // output an escape sequence for the given character code.
    public static int doEscaped(TextWriter @out, char c) {
        StringBuilder escape = new StringBuilder();
        //if (c <= 0xFF) {
        //    escape.Append(Convert.ToString(c, 8));
        //    while (escape.Length < 3)
        //        escape.insert(0, '0');
        //}
        //else {
        //    escape.Append(Convert.ToString(c, 16));
        //    while (escape.Length < 4)
        //        escape.insert(0, '0');
        //    escape.insert(0, 'u');
        //}
        //escape.insert(0, '\\');
        @out.Write(escape.ToString());

        // return Count of bytes this takes up in UTF-8 encoding.
        if (c == 0)
            return 2;
        if (c >= 0x01 && c <= 0x7F)
            return 1;
        if (c >= 0x80 && c <= 0x7FF)
            return 2;
        return 3;
    }

    /* . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . */

    /**
     * Emit the CUPParser subclass with embedded tables.
     * 
     * @param @out              stream to produce output on.
     * @param action_table     internal representation of the actionPart table.
     * @param reduce_table     internal representation of the reduce-goto table.
     * @param start_st         start state of the parse machine.
     * @param start_prod       start production of the grammar.
     * @param compact_reduces  do we use most frequent reduce as default?
     * @param suppress_scanner should scanner be suppressed for compatibility?
     */
    public static void parser(TextWriter @out, ParseActionTable actionTable, ParseReduceTable reduceTable,
        int startSt, ProductionDraft startProd, bool compactReduces, bool suppressScanner) /*throws internal_error*/ {
        long start_time = System.DateTime.Now.Millisecond;

        /* Peek of file */
        System.Console.WriteLine();
        System.Console.WriteLine("//----------------------------------------------------");
        System.Console.WriteLine("// The following code was generated by " + Version.titleStr);
        System.Console.WriteLine("//----------------------------------------------------");
        System.Console.WriteLine();
        emitPackage(@out);

        /* user supplied imports */
        for (int i = 0; i < import_list.Count; i++)
            System.Console.WriteLine("//import " + import_list.ElementAt(i) + ";");
        if (locations)
            System.Console.WriteLine("//import java_cup.runtime.ComplexSymbolFactory.Location;");
        System.Console.WriteLine("//import java_cup.runtime.XMLElement;");

        /* class header */
        System.Console.WriteLine();
        System.Console.WriteLine("/** " + Version.titleStr + " generated CUPParser.");
        System.Console.WriteLine("  */");
        /* TUM changes; proposed by Henning Niss 20050628: added typeArgument */
        System.Console.WriteLine("@SuppressWarnings(\"unused\")");
        System.Console.WriteLine("public class " + parser_class_name + typeArgument + " : java_cup.runtime.LRParser {");

        System.Console.WriteLine();
        System.Console.WriteLine(" @Override");
        System.Console.WriteLine(" public const Class<?> getSymbolContainer() {");
        System.Console.WriteLine("    return " + symbol_const_class_name + ".class;");
        System.Console.WriteLine("}");

        /* constructors [CSA/davidm, 24-jul-99] */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Default constructor. */");
        System.Console.WriteLine("  /*@Deprecated*/");
        System.Console.WriteLine("  public " + parser_class_name + "() {base();}");
        if (!suppressScanner) {
            System.Console.WriteLine();
            System.Console.WriteLine("  /** Constructor which sets the default scanner. */");
            System.Console.WriteLine("  /*@Deprecated*/");
            System.Console.WriteLine("  public " + parser_class_name + "(java_cup.runtime.Scanner s) {base(s);}");
            // TUM 20060327 added SymbolFactory aware constructor
            System.Console.WriteLine();
            System.Console.WriteLine("  /** Constructor which sets the default scanner. */");
            System.Console.WriteLine("  public " + parser_class_name
                + "(java_cup.runtime.Scanner s, java_cup.runtime.SymbolFactory sf) {base(s,sf);}");
        }

        /* emit the various tables */
        emitProductionTable(@out);
        doActionTable(@out, actionTable, compactReduces);
        doReduceTable(@out, reduceTable);

        /* instance of the actionPart encapsulation class */
        System.Console.WriteLine("  /** Instance of actionPart encapsulation class. */");
        System.Console.WriteLine("  public " + pre("actions") + " action_obj;");
        System.Console.WriteLine();

        /* actionPart object initializer */
        System.Console.WriteLine("  /** Action encapsulation object initializer. */");
        System.Console.WriteLine("/*@Override*/");
        System.Console.WriteLine("  public void init_actions()");
        System.Console.WriteLine("    {");
        /* TUM changes; proposed by Henning Niss 20050628: added typeArgument */
        System.Console.WriteLine("      action_obj = new " + pre("actions") + typeArgument + "(this);");
        System.Console.WriteLine("    }");
        System.Console.WriteLine();

        /* access to actionPart code */
        System.Console.WriteLine("  /** Invoke a user supplied parse actionPart. */");
        System.Console.WriteLine("/*@Override*/");
        System.Console.WriteLine("  public java_cup.runtime.TheSymbolDraft do_action(");
        System.Console.WriteLine("    int                        act_num,");
        System.Console.WriteLine("    java_cup.runtime.LRParser CUPParser,");
        System.Console.WriteLine("    java.util.Stack<java_cup.runtime.TheSymbolDraft>    stack,");
        System.Console.WriteLine("    int                        Peek)");
        System.Console.WriteLine("    /*throws java.lang.ExceptionXml*/");
        System.Console.WriteLine("  {");
        System.Console.WriteLine("    /* call code in generated class */");
        System.Console.WriteLine("    return action_obj." + pre("do_action(") + "act_num, CUPParser, stack, Peek);");
        System.Console.WriteLine("  }");
        System.Console.WriteLine("");

        /* method to tell the CUPParser about the start state */
        System.Console.WriteLine("  /** Indicates start state. */");
        System.Console.WriteLine("/*@Override*/");
        System.Console.WriteLine("  public int start_state() {return " + startSt + ";}");

        /* method to indicate start production */
        System.Console.WriteLine("  /** Indicates start production. */");
        System.Console.WriteLine("/*@Override*/");
        System.Console.WriteLine("  public int firstProduction() {return " + firstProduction.Index + ";}");
        System.Console.WriteLine();

        /* methods to indicate EOF and error SymbolDraft indexes */
        System.Console.WriteLine("  /** <code>EOF</code> TheSymbolDraft index. */");
        System.Console.WriteLine("/*@Override*/");
        System.Console.WriteLine("  public int EOF_sym() {return " + Vt.EOF.Index + ";}");
        System.Console.WriteLine();
        System.Console.WriteLine("  /** <code>error</code> TheSymbolDraft index. */");
        System.Console.WriteLine("/*@Override*/");
        System.Console.WriteLine("  public int error_sym() {return " + Vt.error.Index + ";}");
        System.Console.WriteLine();

        /* user supplied code for user_init() */
        if (init_code != null) {
            System.Console.WriteLine();
            System.Console.WriteLine("  /** User initialization code. */");
            System.Console.WriteLine("  public void user_init() /*throws java.lang.ExceptionXml*/");
            System.Console.WriteLine("    {");
            System.Console.WriteLine(init_code);
            System.Console.WriteLine("    }");
        }

        /* user supplied code for scan */
        if (scan_code != null) {
            System.Console.WriteLine();
            System.Console.WriteLine("  /** Scan to get the next TheSymbolDraft. */");
            System.Console.WriteLine("/*@Override*/");
            System.Console.WriteLine("  public java_cup.runtime.TheSymbolDraft scan()");
            System.Console.WriteLine("    /*throws java.lang.ExceptionXml*/");
            System.Console.WriteLine("    {");
            System.Console.WriteLine(scan_code);
            System.Console.WriteLine("    }");
        }

        /* user supplied code */
        if (parser_code != null) {
            System.Console.WriteLine();
            System.Console.WriteLine(parser_code);
        }

        /* put @out the actionPart code class */
        if (!_xmlactions)
            EmitActionCode(@out, startProd);
        else
            emitXmlactionCode(@out, startProd);

        /* end of class */
        System.Console.WriteLine("}");

        parser_time = System.DateTime.Now.Millisecond - start_time;
    }

    /**
     * Emit code for generic XML parsetree output.
     * 
     * @param @out        stream to produce output on.
     * @param start_prod the start production of the grammar.
     */
    public static void emitXmlactionCode(TextWriter @out, ProductionDraft startProd) /*throws internal_error*/ {
        ProductionDraft prod;

        long start_time = System.DateTime.Now.Millisecond;

        /* class header */
        System.Console.WriteLine();
        System.Console.WriteLine("/** Cup generated class to encapsulate user supplied actionPart code.*/");
        System.Console.WriteLine("class " + pre("actions") + typeArgument + " {");
        /* user supplied code */
        if (action_code != null) {
            System.Console.WriteLine();
            System.Console.WriteLine(action_code);
        }

        /* field for CUPParser object */
        System.Console.WriteLine("  public const " + parser_class_name + typeArgument + " CUPParser;");

        /* constructor */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Constructor */");
        System.Console.WriteLine("  " + pre("actions") + "(" + parser_class_name + typeArgument + " CUPParser) {");
        System.Console.WriteLine("    this.CUPParser = CUPParser;");
        System.Console.WriteLine("  }");

        System.Console.WriteLine();
        for (int instancecounter = 0; instancecounter <= ProductionDraft.Count / UPPERLIMIT; instancecounter++) {
            System.Console.WriteLine("  /** Method " + instancecounter + " with the actual generated actionPart code for actions "
                + (instancecounter * UPPERLIMIT) + " to " + ((instancecounter + 1) * UPPERLIMIT) + ". */");
            System.Console.WriteLine("  public const java_cup.runtime.TheSymbolDraft " + pre("do_action_part")
                + String.Format("%08d", instancecounter) + "(");
            System.Console.WriteLine("    int                        " + pre("act_num,"));
            System.Console.WriteLine("    java_cup.runtime.LRParser " + pre("CUPParser,"));
            System.Console.WriteLine("    java.util.Stack<java_cup.runtime.TheSymbolDraft>    " + pre("stack,"));
            System.Console.WriteLine("    int                        " + pre("Peek)"));
            System.Console.WriteLine("    /*throws java.lang.ExceptionXml*/");
            System.Console.WriteLine("    {");
            System.Console.WriteLine("      /* TheSymbolDraft object for return from actions */");
            System.Console.WriteLine("      java_cup.runtime.TheSymbolDraft " + pre("result") + ";");
            System.Console.WriteLine();
            System.Console.WriteLine("      /* select the actionPart based on the actionPart Count */");
            System.Console.WriteLine("      switch (" + pre("act_num") + ")");
            System.Console.WriteLine("        {");
            // START Switch
            /* emit actionPart code for each production as a separate case */
            int proditeration = instancecounter * UPPERLIMIT;
            prod = ProductionDraft.Find(proditeration);
            for (; proditeration < Math.Min((instancecounter + 1) * UPPERLIMIT,
                ProductionDraft.Count); prod = ProductionDraft.Find(++proditeration)) {
                /* case label */
                System.Console.WriteLine("          /*. . . . . . . . . . . . . . . . . . . .*/");
                System.Console.WriteLine("          case " + prod.Index + ": // " + prod.toSimpleString());

                /* give them their own block to work in */
                System.Console.WriteLine("            {");

                System.Console.WriteLine("                XMLElement RESULT;");

                // Generate the XML Output
                String nested = "";
                for (int rhsi = 0; rhsi < prod.rhsLength; rhsi++) {
                    if (!(prod.rhs(rhsi) is SymbolPart))
                        continue;
                    String label = prod.rhs(rhsi).Label;
                    SymbolPart sym = (SymbolPart)prod.rhs(rhsi);
                    if (label == null) {
                        if (!_genericlabels)
                            continue;
                        label = sym.TheSymbolDraft.Name + rhsi;
                    }
                    if (sym.TheSymbolDraft.IsVn)
                        nested += ",(XMLElement)" + label;
                    else
                        nested += ",new XMLElement.TerminalXml(" + label + "xleft,\"" + label + "\"," + label + "," + label
                            + "xright)";
                }

                if (prod.actionPart != null && prod.actionPart.CodeString != null && !prod.actionPart.Equals(""))
                    System.Console.WriteLine(prod.actionPart.CodeString);

                // determine the variant:
                int variant = 0;
                for (int i = 0; i < proditeration; i++)
                    if (ProductionDraft.Find(i).lhs.Equals(prod.lhs))
                        variant++;

                String lhsname = prod.lhs.TheSymbolDraft.Name.Replace('$', '_');
                System.Console.WriteLine(
                    "                RESULT = new XMLElement.NonTerminalXml(\"" + lhsname + "\"," + variant + nested + ");");

                /*
                 * Create the code that assigns the _left and _right values of the new TheSymbolDraft that
                 * the production is reducing to
                 */
                if (Emit.lrValues) {
                    int loffset;
                    String leftstring, rightstring;
                    rightstring = Emit.pre("stack") + ".Peek()";
                    if (prod.rhsLength == 0)
                        leftstring = rightstring;
                    else {
                        loffset = prod.rhsLength - 1;
                        leftstring = Emit.pre("stack")
                            + ((loffset == 0) ? (".Peek()") : (".ElementAt(" + Emit.pre("Peek") + "-" + loffset + ")"));
                    }
                    System.Console.WriteLine("              " + pre("result") + " = CUPParser.getSymbolFactory().newSymbol(" + "\""
                        + prod.lhs.TheSymbolDraft.Name + "\"," + prod.lhs.TheSymbolDraft.Index + ", " + leftstring + ", "
                        + rightstring + ", RESULT);");
                }
                else {
                    System.Console.WriteLine("              " + pre("result") + " = CUPParser.getSymbolFactory().newSymbol(" + "\""
                        + prod.lhs.TheSymbolDraft.Name + "\"," + prod.lhs.TheSymbolDraft.Index + ", RESULT);");
                }

                /* end of their block */
                System.Console.WriteLine("            }");

                /* if this was the start production, do actionPart for accept */
                if (prod == startProd) {
                    System.Console.WriteLine("          /* ACCEPT */");
                    System.Console.WriteLine("          " + pre("CUPParser") + ".done_parsing();");
                }

                /* code to return lhs SymbolDraft */
                System.Console.WriteLine("          return " + pre("result") + ";");
                System.Console.WriteLine();
            }

            // END Switch
            System.Console.WriteLine("          /* . . . . . .*/");
            System.Console.WriteLine("          default:");
            System.Console.WriteLine("            throw new ExceptionXml(");
            System.Console.WriteLine(
                "               \"Invalid actionPart Count \"+" + pre("act_num") + "+\"found in " + "internal parse table\");");
            System.Console.WriteLine();
            System.Console.WriteLine("        }");
            System.Console.WriteLine("    } /* end of method */");
        }

        /* actionPart method head */
        System.Console.WriteLine();
        System.Console.WriteLine("  /** Method splitting the generated actionPart code into several parts. */");
        System.Console.WriteLine("  public const java_cup.runtime.TheSymbolDraft " + pre("do_action") + "(");
        System.Console.WriteLine("    int                        " + pre("act_num,"));
        System.Console.WriteLine("    java_cup.runtime.LRParser " + pre("CUPParser,"));
        System.Console.WriteLine("    java.util.Stack<java_cup.runtime.TheSymbolDraft>    " + pre("stack,"));
        System.Console.WriteLine("    int                        " + pre("Peek)"));
        System.Console.WriteLine("    /*throws java.lang.ExceptionXml*/");
        System.Console.WriteLine("    {");

        if (ProductionDraft.Count < UPPERLIMIT) { // Make it simple for the optimizer to inline!
            System.Console.WriteLine("              return " + pre("do_action_part") + String.Format("%08d", 0) + "(");
            System.Console.WriteLine("                               " + pre("act_num,"));
            System.Console.WriteLine("                               " + pre("CUPParser,"));
            System.Console.WriteLine("                               " + pre("stack,"));
            System.Console.WriteLine("                               " + pre("Peek);"));
            System.Console.WriteLine("    }");

            /* end of class */
            System.Console.WriteLine("}");
            System.Console.WriteLine();

            action_code_time = System.DateTime.Now.Millisecond - start_time;
            return;
        }

        /* switch Peek */
        System.Console.WriteLine("      /* select the actionPart handler based on the actionPart Count */");
        System.Console.WriteLine("      switch (" + pre("act_num") + "/" + UPPERLIMIT + ")");
        System.Console.WriteLine("        {");

        /* emit actionPart code for each production as a separate case */
        for (int instancecounter = 0; instancecounter <= ProductionDraft.Count / UPPERLIMIT; instancecounter++) {
            /* case label */
            System.Console.WriteLine("          /*. . . . . . . . " + (instancecounter * UPPERLIMIT) + " < #actionPart < "
                + ((instancecounter + 1) * UPPERLIMIT) + ". . . . . . . . . . . .*/");
            System.Console.WriteLine("          case " + instancecounter + ": ");
            System.Console.WriteLine("              return " + pre("do_action_part")
                + String.Format("%08d", instancecounter) + "(");
            System.Console.WriteLine("                               " + pre("act_num,"));
            System.Console.WriteLine("                               " + pre("CUPParser,"));
            System.Console.WriteLine("                               " + pre("stack,"));
            System.Console.WriteLine("                               " + pre("Peek);"));
        }

        System.Console.WriteLine("          /* . . . no valid actionPart Count: . . .*/");
        System.Console.WriteLine("          default:");
        System.Console.WriteLine("            throw new ExceptionXml(\"Invalid actionPart Count found in internal parse table\");");
        System.Console.WriteLine();
        System.Console.WriteLine("        }      /* end of switch */");

        /* end of method */
        System.Console.WriteLine("    }");

        /* end of class */
        System.Console.WriteLine("}");
        System.Console.WriteLine();

        action_code_time = System.DateTime.Now.Millisecond - start_time;
    }

    /*-----------------------------------------------------------*/
}
